package nb.diskfilesystem;

import javafx.animation.FadeTransition;
import javafx.animation.Interpolator;
import javafx.animation.ParallelTransition;
import javafx.animation.TranslateTransition;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.control.*;
import javafx.scene.input.MouseButton;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.TilePane;
import javafx.geometry.Pos;
import javafx.scene.control.Label;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
import javafx.util.Duration;
import nb.diskfilesystem.controller.FileEditorController;
import nb.diskfilesystem.controller.MainController;

import java.util.ArrayList;
import java.util.List;

public class ViewHandler {
    private TreeView<String> directoryTreeView;
    private TilePane fileArea;
    private FileContextMenu fileContextMenu;
    public static String curentFilePath;     //全局监听路径
    private TextField viewfilePat=(TextField) MainController.rootNode.lookup("#viewfilePath");
    public static String filePath = "C盘\\"; // 初始化为根目录路径


    private static boolean isFileOpen = false; // 记录文件是否已经打开

    public ViewHandler(TreeView<String> directoryTreeView, TilePane fileArea,FileContextMenu fileContextMenu) {
        this.directoryTreeView = directoryTreeView;
        this.fileArea = fileArea;
        this.fileContextMenu=fileContextMenu;


    }

    public void addTreeViewListener() {
        directoryTreeView.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue != null) {
                filePath = getFilePath(newValue);
                List<String> test = DirectoryTreeBuilder.getFilesInDirectory(filePath);//可以获取到当前点击的那个子节点（）只需要修改一下这个方法
                updateFileArea(filePath);     //根据得到的filePath去更新目录项
                curentFilePath=filePath;      //设置为全局路径
                viewfilePat.setText(filePath);
                System.out.println("当前所选路径为"+curentFilePath);     //点击文件夹旧可以获取当前路径


            }
        });
    }

    //得到该文件夹的路径
    private String getFilePath(TreeItem<String> treeItem) {
        StringBuilder filePath = new StringBuilder();
        TreeItem<String> current = treeItem;
        while (current != null) {
            filePath.insert(0, current.getValue() + "\\");
            current = current.getParent();
        }
        return filePath.toString();
    }

    //点击目录项更新项目
    public void updateFileArea(String filePath) {
        fileArea.getChildren().clear();    //先清空fileArea
        List<String> files = DirectoryTreeBuilder.getFilesInDirectory(filePath);

        for (String file : files) {
            BorderPane borderPane = new BorderPane();
            borderPane.getStylesheets().add(getClass().getResource("/nb/diskfilesystem/css/border.css").toExternalForm());
            borderPane.getStyleClass().add("borderpane");
            borderPane.setPrefSize(100, 100);

            setBorderhandler(borderPane);

            Pane centerPane = new Pane();
            centerPane.getStyleClass().add("pane");
            borderPane.setCenter(centerPane);

            Label label = new Label(file);
            borderPane.setBottom(label);
            BorderPane.setAlignment(label, Pos.CENTER);

            Directory_Node node = DirectoryTreeBuilder.getNodeByName(filePath, file);
            if (node != null && node.getAttribute() == 8) {
                centerPane.getStylesheets().add(getClass().getResource("/nb/diskfilesystem/css/folder.css").toExternalForm());
            } else {
                centerPane.getStylesheets().add(getClass().getResource("/nb/diskfilesystem/css/file.css").toExternalForm());
            }

            fileArea.getChildren().add(borderPane);

        }
    }

    //文件或者目录被点击后的变色状态
    public    void  setBorderhandler(BorderPane borderPane){
        borderPane.setOnMouseClicked(event -> {
            // 移除其他FileItem的选中样式
            fileArea.getChildren().forEach(node -> {
                if (node instanceof BorderPane && node != borderPane) {
                    node.getStyleClass().remove("borderpane-selected");
                }
            });
            fileContextMenu.getBlockContextMenu().hide(); // 隐藏空白区域右键菜单
            // 添加选中样式
            if (!borderPane.getStyleClass().contains("borderpane-selected")) {
                borderPane.getStyleClass().add("borderpane-selected");
            }

            // 如果是右键点击，显示文件右键菜单
            if (event.getButton() == MouseButton.SECONDARY) {
                animateContextMenu(true, fileContextMenu.getFileContextMenu());
                fileContextMenu.getFileContextMenu().show(borderPane, event.getScreenX(), event.getScreenY());

            }
            // 判断是否为双击事件
            if (event.getClickCount() == 2) {
                Label label = (Label) borderPane.getBottom(); // 获取 BorderPane 底部的 Label
                String nodeName = label.getText(); // 获取文件或目录名称
                System.out.println("鼠标左键双击"+nodeName);//确实是点击的文件
                // 根据文件名调用打开文件方法
                //openDirectroy_Node(fileName); // 假设 openFile 是你要调用的文件打开方法
                if (!isFileOpen) { // 检查文件是否已经打开
                    System.out.println("鼠标左键双击打开文件成功");
                    try {
                        handleLeftClick(nodeName);
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                } else {
                    System.out.println("文件已打开，禁止再次打开");
                }
            }
            event.consume();
        });

    }

    // 动画效果
    public static void animateContextMenu(boolean show, ContextMenu contextMenu) {
        contextMenu.getScene().getRoot().applyCss();
        contextMenu.getScene().getRoot().layout();

        TranslateTransition translateTransition = new TranslateTransition(Duration.millis(185), contextMenu.getScene().getRoot());
        FadeTransition fadeTransition = new FadeTransition(Duration.millis(185), contextMenu.getScene().getRoot());

        translateTransition.setInterpolator(Interpolator.EASE_BOTH);
        fadeTransition.setInterpolator(Interpolator.EASE_BOTH);

        if (show) {
            translateTransition.setFromY(-contextMenu.getHeight());
            translateTransition.setToY(0);
            fadeTransition.setFromValue(0);
            fadeTransition.setToValue(1);
        } else {
            translateTransition.setFromY(0);
            translateTransition.setToY(-contextMenu.getHeight());
            fadeTransition.setFromValue(1);
            fadeTransition.setToValue(0);
        }

        ParallelTransition parallelTransition = new ParallelTransition(translateTransition, fadeTransition);
        parallelTransition.play();
    }

    //判断是文件还是文件夹
    private void handleLeftClick(String nodeName) throws Exception {
        String currentPath = ViewHandler.filePath;
        System.out.println(currentPath);
        Directory_Node currentNode = DirectoryTreeBuilder.getNodeByName(currentPath, nodeName);
        if (currentNode.getAttribute() == 8) { // 如果是文件夹
            System.out.println("判断是文件夹，准备进入目录");
            // 更新当前路径
            ViewHandler.filePath = currentPath + nodeName + "\\";
            ViewHandler.curentFilePath = ViewHandler.filePath;

            // 更新文件区域显示
            updateFileArea(ViewHandler.filePath);

            // 更新路径显示
            TextField viewfilePath = (TextField) MainController.rootNode.lookup("#viewfilePath");
            if (viewfilePath != null) {
                viewfilePath.setText(ViewHandler.filePath);
            }

            // 更新目录树选中状态
            updateTreeViewSelection(nodeName);
        } else {
            openDirectroy_Node(currentNode);
        }
    }

    // 修改更新目录树选中状态的方法
    private void updateTreeViewSelection(String folderName) {
        TreeItem<String> root = directoryTreeView.getRoot();
        String[] pathParts = ViewHandler.filePath.split("\\\\");
        TreeItem<String> current = root;

        // 遍历路径的每一部分
        for (String part : pathParts) {
            if (part.equals("C盘") || part.isEmpty()) {
                continue;
            }

            // 在当前节点的子节点中查找匹配的节点
            for (TreeItem<String> child : current.getChildren()) {
                if (child.getValue().equals(part)) {
                    child.setExpanded(true);  // 展开找到的节点
                    directoryTreeView.getSelectionModel().select(child); // 选中该节点
                    current = child;
                    break;
                }
            }
        }
    }

    public static  void openDirectroy_Node(Directory_Node currentNode){
        try {
            // 加载新窗口的 FXML 文件
            FXMLLoader loader = new FXMLLoader(ViewHandler.class.getResource("/nb/diskfilesystem/textfield.fxml"));
            BorderPane slideshowRoot = loader.load();//初始化完了
            //获取幻灯片控制器并初始化图片列
            FileEditorController fileEditorController = loader.getController();
            System.out.println("回到MainController,开始传imageFiles");
            // 传递节点对象到新窗口
            fileEditorController.setDirectoryEntry(currentNode); // currentNode中 包含文件的文字（如文件名）
            // 设置文件已打开
            isFileOpen = true;
            //创建和显示幻灯片界面的窗口
            Scene scene = new Scene(slideshowRoot);
            Stage slideshowStage = new Stage();
            slideshowStage.setScene(scene);
            slideshowStage.setTitle("文件编辑");
            //创建了一个新的场景，并将加载的FXML文件的根节点设置为该场景的根节点。
            // 设置Stage的最小宽度和高度
            slideshowStage.setMinWidth(400);
            slideshowStage.setMinHeight(600);

            slideshowStage.setOnHidden(new EventHandler<WindowEvent>() {
                @Override
                public void handle(WindowEvent event) {
                    // 当窗口关闭时，重置文件打开状态
                    isFileOpen = false;
                }
            });
            slideshowStage.show();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 在ViewHandler类中添加搜索方法
    public void searchFiles(String keyword) {
        if (keyword == null || keyword.trim().isEmpty()) {
            // 如果搜索关键词为空，恢复显示当前目录的内容
            updateFileArea(ViewHandler.filePath);
            return;
        }


        // 清空当前fileArea
        fileArea.getChildren().clear();

        // 从根目录开始搜索
        List<Directory_Node> searchResults = new ArrayList<>();
        searchInNode(DirectoryTreeBuilder.rootDirectory_Node, keyword.toLowerCase(), searchResults);

        // 显示搜索结果
        for (Directory_Node node : searchResults) {
            BorderPane borderPane = new BorderPane();
            borderPane.getStylesheets().add(getClass().getResource("/nb/diskfilesystem/css/border.css").toExternalForm());
            borderPane.getStyleClass().add("borderpane");
            borderPane.setPrefSize(100, 100);

            // 设置边框处理器
            fileContextMenu.setBorderhandler(borderPane);
            setBorderhandler(borderPane);

            Pane centerPane = new Pane();
            centerPane.getStyleClass().add("pane");

            // 根据节点类型设置不同的样式
            if (node.getAttribute() == 8) {
                centerPane.getStylesheets().add(getClass().getResource("/nb/diskfilesystem/css/folder.css").toExternalForm());
            } else {
                centerPane.getStylesheets().add(getClass().getResource("/nb/diskfilesystem/css/file.css").toExternalForm());
            }

            borderPane.setCenter(centerPane);

            // 显示文件名
            String fileName = new String(node.getFile_Name()).trim();
            Label label = new Label(fileName);
            borderPane.setBottom(label);
            BorderPane.setAlignment(label, Pos.CENTER);

            fileArea.getChildren().add(borderPane);
        }
    }

    // 递归搜索方法
    private void searchInNode(Directory_Node node, String keyword, List<Directory_Node> results) {
        if (node == null) return;

        // 检查当前节点的文件名是否包含关键词
        String fileName = new String(node.getFile_Name()).trim().toLowerCase();
        if (fileName.contains(keyword)) {
            results.add(node);
        }

        // 递归搜索子节点
        if (node.getChildrens() != null) {
            for (Directory_Node child : node.getChildrens()) {
                searchInNode(child, keyword, results);
            }
        }
    }


}